package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.service.AlbumAttributeValueService;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.album.service.AlbumStatService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.album.AlbumAttributeValue;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.AlbumStat;
import com.atguigu.tingshu.query.album.AlbumInfoQuery;
import com.atguigu.tingshu.vo.album.AlbumAttributeValueVo;
import com.atguigu.tingshu.vo.album.AlbumInfoVo;
import com.atguigu.tingshu.vo.album.AlbumListVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;


/**
 * @author sun
 */
@Slf4j
@Service
public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo> implements AlbumInfoService {

    @Resource
    private AlbumInfoMapper albumInfoMapper;

    @Resource
    private AlbumAttributeValueService albumAttributeValueService;

    @Resource
    private AlbumStatService albumStatService;

    @Resource
    private RabbitTemplate rabbitTemplate;

    /**
     * 新增专辑
     *
     * @param albumInfoVo 专辑的Vo信息
     */
    @Override
    @Transactional
    public void saveAlbumInfo(AlbumInfoVo albumInfoVo) {

        AlbumInfo albumInfo = new AlbumInfo();
        BeanUtils.copyProperties(albumInfoVo, albumInfo);
        albumInfo.setStatus(SystemConstant.ALBUM_STATUS_NO_PASS);
        albumInfo.setUserId(AuthContextHolder.getUserId());
        //付费专辑前5集免费试看
        if (!albumInfoVo.getPayType().equals(SystemConstant.ALBUM_PAY_TYPE_FREE)) {
            albumInfo.setTracksForFree(5);
        }
        int insert = albumInfoMapper.insert(albumInfo);
        if (insert < 1) {
            throw new GuiguException(ResultCodeEnum.ALBUM_SAVE_ERROR);
        }

        //保存属性值-->保存到关系表
        List<AlbumAttributeValueVo> albumAttributeValueVos = albumInfoVo.getAlbumAttributeValueVoList();

        if (!CollectionUtils.isEmpty(albumAttributeValueVos)) {
            List<AlbumAttributeValue> albumAttributeValues = albumAttributeValueVos.stream().map(albumAttributeValueVo ->
                    AlbumAttributeValue.builder()
                            .attributeId(albumAttributeValueVo.getAttributeId())
                            .valueId(albumAttributeValueVo.getValueId())
                            .albumId(albumInfo.getId())
                            .build()
            ).collect(toList());

            boolean saveBatch = albumAttributeValueService.saveBatch(albumAttributeValues);
            if (!saveBatch) {
                throw new GuiguException(ResultCodeEnum.ALBUM_SAVE_ERROR);
            }
        }

        // 初始化统计信息
        String[] statTypes = {
                SystemConstant.ALBUM_STAT_BROWSE,
                SystemConstant.ALBUM_STAT_COMMENT,
                SystemConstant.ALBUM_STAT_PLAY,
                SystemConstant.ALBUM_STAT_SUBSCRIBE
        };
        List<AlbumStat> albumStats = Arrays.stream(statTypes).map(statType -> AlbumStat.builder()
                .albumId(albumInfo.getId())
                .statType(statType)
                .statNum(0)
                .build()).collect(toList());
        boolean saveBatch = albumStatService.saveBatch(albumStats);
        if (!saveBatch) {
            throw new GuiguException(ResultCodeEnum.ALBUM_SAVE_ERROR);
        }
        // 专辑公开则将数据 同步在es中
        if ("1".equals(albumInfoVo.getIsOpen())) {
            rabbitTemplate.convertAndSend("album_search_exchange", "album_search_add", albumInfo.getId());
        }
    }

    /**
     * 查询用户专辑分页
     *
     * @param albumInfoQuery 查询条件
     * @param page           页
     * @param size           每页记录数
     * @return 专辑展示VO列表
     */
    @Override
    public IPage<AlbumListVo> findUserAlbumPage(AlbumInfoQuery albumInfoQuery, Long page, Long size) {
        Page<AlbumListVo> albumInfoPage = new Page<>(page, size);
        return albumInfoMapper.findUserAlbumPage(albumInfoPage, albumInfoQuery);
    }

    /**
     * 删除专辑
     *
     * @param albumId 专辑id
     */
    @Override
    @Transactional
    public Integer removeAlbumInfo(Long albumId) {
        // 1、删除专辑
        int delete = albumInfoMapper.deleteById(albumId);
        if (delete < 1) {
            throw new GuiguException(ResultCodeEnum.ALBUM_DELETE_ERROR);
        }
        // 2、删除专辑属性值
        boolean remove = albumAttributeValueService.remove(new LambdaQueryWrapper<AlbumAttributeValue>()
                .eq(AlbumAttributeValue::getAlbumId, albumId));
        if (!remove) {
            throw new GuiguException(ResultCodeEnum.ALBUM_DELETE_ERROR);
        }
        // 3、删除专辑统计信息
        boolean remove1 = albumStatService.remove(new LambdaQueryWrapper<AlbumStat>()
                .eq(AlbumStat::getAlbumId, albumId));
        if (!remove1) {
            throw new GuiguException(ResultCodeEnum.ALBUM_DELETE_ERROR);
        }
        // 4、删除专辑索引
        rabbitTemplate.convertAndSend("album_search_exchange", "album_search_delete", albumId);
        return delete;
    }

    /**
     * 查询专辑信息
     *
     * @param albumId 专辑id
     * @return 专辑信息
     */
    @Override
    @Transactional
    public AlbumInfo getAlbumInfo(Long albumId) {
        // 1、查询专辑信息
        AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
        // 2、查询专辑属性值
        if (albumInfo != null) {
            List<AlbumAttributeValue> albumAttributeValueList = albumAttributeValueService.list(new LambdaQueryWrapper<AlbumAttributeValue>()
                    .eq(AlbumAttributeValue::getAlbumId, albumId));
            albumInfo.setAlbumAttributeValueVoList(albumAttributeValueList);
        }
        return albumInfo;
    }

    /**
     * 修改专辑信息
     *
     * @param albumId     专辑id
     * @param albumInfoVo 专辑VO信息
     */
    @Override
    @Transactional
    public Integer updateAlbumInfo(Long albumId, AlbumInfoVo albumInfoVo) {
        // 1、修改专辑信息
        AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
        BeanUtils.copyProperties(albumInfoVo, albumInfo);
        albumInfo.setUpdateTime(new Date());
        int result = albumInfoMapper.updateById(albumInfo);
        // 2、修改专辑属性值
        //先删后插
        boolean remove = albumAttributeValueService.remove(new LambdaQueryWrapper<AlbumAttributeValue>()
                .eq(AlbumAttributeValue::getAlbumId, albumId));
        if (remove) {
            List<AlbumAttributeValueVo> albumAttributeValueVos = albumInfoVo.getAlbumAttributeValueVoList();
            if (!CollectionUtils.isEmpty(albumAttributeValueVos)) {
                List<AlbumAttributeValue> albumAttributeValues = albumAttributeValueVos.stream().map(albumAttributeValueVo ->
                        AlbumAttributeValue.builder()
                                .attributeId(albumAttributeValueVo.getAttributeId())
                                .valueId(albumAttributeValueVo.getValueId())
                                .albumId(albumInfo.getId())
                                .build()
                ).collect(toList());
                boolean saveBatch = albumAttributeValueService.saveBatch(albumAttributeValues);
                if (!saveBatch) {
                    throw new GuiguException(ResultCodeEnum.ALBUM_UPDAtE_ERROR);
                }
            }
        } else {
            throw new GuiguException(ResultCodeEnum.ALBUM_UPDAtE_ERROR);
        }
        if ("1".equals(albumInfoVo.getIsOpen())) {
            // 专辑为公开则在es中添加数据
            rabbitTemplate.convertAndSend("album_search_exchange", "album_search_add", albumId);
        } else {
            // 专辑为非公开则在es中删除索引
            rabbitTemplate.convertAndSend("album_search_exchange", "album_search_delete", albumId);
        }


        return result;
    }

    /**
     * 查询用户所有专辑列表--只包含专辑id和专辑标题
     *
     * @return 专辑列表--只包含专辑id和专辑标题
     */
    @Override
    public List<AlbumInfo> findUserAllAlbumList() {
        return albumInfoMapper.selectList(new LambdaQueryWrapper<AlbumInfo>()
                .select(AlbumInfo::getId, AlbumInfo::getAlbumTitle)
                .eq(AlbumInfo::getUserId, AuthContextHolder.getUserId())
                .orderByDesc(AlbumInfo::getCreateTime));
    }

    /**
     * 获取专辑统计信息
     *
     * @param id 专辑id
     * @return 专辑统计信息
     */
    @Override
    public Map<String, Integer> getAlbumStats(Long id) {
        List<AlbumStat> list = albumStatService.list(new LambdaQueryWrapper<AlbumStat>()
                .eq(AlbumStat::getAlbumId, id)
        );
        return list.stream().collect(Collectors.toMap(
                AlbumStat::getStatType,
                AlbumStat::getStatNum
        ));
    }

    /**
     * 获取专辑的标签
     *
     * @param id 专辑id
     * @return 标签列表
     */
    @Override
    public List<AlbumAttributeValue> getAlbumAttributes(Long id) {
        return albumAttributeValueService.list(new LambdaQueryWrapper<AlbumAttributeValue>()
                .eq(AlbumAttributeValue::getAlbumId, id)
        );
    }
}
